{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 分类训练"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 机器学习的HelloWorld ，一个新的分类算法，都会看看在MNIST的上的执行结果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "b'\\x00\\x00\\x00\\x02'"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import struct\n",
    "struct.pack('>i',2) # 高位字节"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "![jupyter](./g1.png)\n",
    "![jupyter](./g2.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(2051, 60000, 28, 28)\n",
      "47040000\n"
     ]
    }
   ],
   "source": [
    "import struct\n",
    "with open('./MNIST_data/train-images-idx3-ubyte', 'rb') as f:\n",
    "    buffer = f.read(4*4) # 4个int\n",
    "    head = struct.unpack('>iiii',buffer)\n",
    "    print(head)\n",
    "    length = head[1] * head[2]  * head[3]\n",
    "    print(length)\n",
    "    buffer = f.read(length)\n",
    "#   print(buffer)\n",
    "    data = struct.unpack('>{}B'.format(length),buffer)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "47040000"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tuple"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "imgs = np.reshape(data, (head[1], head[2], head[3]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(60000, 28, 28)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "imgs.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "for i in range(5):\n",
    "    plt.imshow(imgs[i], cmap = 'gray')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\users\\administrator\\appdata\\local\\programs\\python\\python37\\lib\\site-packages\\sklearn\\utils\\deprecation.py:85: DeprecationWarning: Function fetch_mldata is deprecated; fetch_mldata was deprecated in version 0.20 and will be removed in version 0.22. Please use fetch_openml.\n",
      "  warnings.warn(msg, category=DeprecationWarning)\n",
      "c:\\users\\administrator\\appdata\\local\\programs\\python\\python37\\lib\\site-packages\\sklearn\\utils\\deprecation.py:85: DeprecationWarning: Function mldata_filename is deprecated; mldata_filename was deprecated in version 0.20 and will be removed in version 0.22. Please use fetch_openml.\n",
      "  warnings.warn(msg, category=DeprecationWarning)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.datasets import fetch_mldata\n",
    "mnist = fetch_mldata('MNIST original', data_home='./')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'DESCR': 'mldata.org dataset: mnist-original',\n",
       " 'COL_NAMES': ['label', 'data'],\n",
       " 'target': array([0., 0., 0., ..., 9., 9., 9.]),\n",
       " 'data': array([[0, 0, 0, ..., 0, 0, 0],\n",
       "        [0, 0, 0, ..., 0, 0, 0],\n",
       "        [0, 0, 0, ..., 0, 0, 0],\n",
       "        ...,\n",
       "        [0, 0, 0, ..., 0, 0, 0],\n",
       "        [0, 0, 0, ..., 0, 0, 0],\n",
       "        [0, 0, 0, ..., 0, 0, 0]], dtype=uint8)}"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mnist"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* DESCR 数据集描述\n",
    "* data 包含一个数组，每个实例为一行，每个特征为一列\n",
    "* target 包含一个带有标签的数组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "X, y = mnist['data'], mnist['target']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(70000, 784)"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(70000,)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "some_digit = X[36000]\n",
    "some_digit_image = some_digit.reshape(28, 28)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(some_digit_image, cmap = matplotlib.cm.binary)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5.0"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y[36000]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 建立测试集和训练集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 8498, 56531, 10216, ..., 44292, 40725, 38159])"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 将数据集合交叉洗牌，交叉验证时，每个子集合数据分布均匀，有些机器学习算法对训练实例的顺序敏感\n",
    "import numpy as np\n",
    "shuffle_index = np.random.permutation(60000)\n",
    "shuffle_index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train, y_train = X_train[shuffle_index], y_train[shuffle_index]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       ...,\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0],\n",
       "       [0, 0, 0, ..., 0, 0, 0]], dtype=uint8)"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练一个二元分类器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False, False, False, ..., False, False, False])"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 识别数字5 ，二元分类5或者非5\n",
    "# 创建目标向量\n",
    "y_train_5 = (y_train == 5)\n",
    "y_train_5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[False, False, False, ..., False, False, False],\n",
       "       [False, False, False, ..., False, False, False],\n",
       "       [False, False, False, ..., False, False, False],\n",
       "       ...,\n",
       "       [False, False, False, ..., False, False, False],\n",
       "       [False, False, False, ..., False, False, False],\n",
       "       [False, False, False, ..., False, False, False]])"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_5.reshape(20, -1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_test_5 = (y_test == 5) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ True])"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# SGD 梯度下降 分类器， 适合非常大的数据集，独立处理训练集数据，一次一个，适合在线学习，\n",
    "from sklearn.linear_model import SGDClassifier\n",
    "\n",
    "sgd_clf = SGDClassifier(random_state = 42)\n",
    "sgd_clf.fit(X_train, y_train_5)\n",
    "\n",
    "sgd_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 性能考核"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 使用交叉验证测量精度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.9455 , 0.96295, 0.9615 ])"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 评估分类器比评估回归器要困难得多\n",
    "\n",
    "# 3个折叠，正确率达到 95% 以上\n",
    "from sklearn.model_selection import cross_val_score\n",
    "cross_val_score(sgd_clf, X_train, y_train_5, cv=3, scoring=\"accuracy\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 把每张图都分类成 非5\n",
    "from sklearn.base import BaseEstimator\n",
    "class Never5Classifier(BaseEstimator):\n",
    "    def fit(self, X, y=None):\n",
    "        pass\n",
    "    def predict(self, X):\n",
    "        return np.zeros((len(X), 1), dtype=bool)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[False],\n",
       "       [False],\n",
       "       [False],\n",
       "       ...,\n",
       "       [False],\n",
       "       [False],\n",
       "       [False]])"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.zeros((len(X), 1), dtype=bool)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.9084 , 0.91115, 0.9094 ])"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "never_5_clf = Never5Classifier()\n",
    "cross_val_score(never_5_clf, X_train, y_train_5, cv=3, scoring=\"accuracy\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 准确率超过90% ，因为5的图像大约只有10%，你猜一张图不是5， 90%的时间你都是正确的\n",
    "* 这说明准确率无法成为分类器的首要性能指标，特别是当你处理偏科数据集， 某些类比其他类更为频繁"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 混淆矩阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 评估分类器性能的更好方法是混淆矩阵\n",
    "# A类别实例被分为B类别次数\n",
    "# 想要知道分类器将数字3和数字5混淆多少次，通过混淆矩阵的5行3列\n",
    "from sklearn.model_selection import cross_val_predict\n",
    "\n",
    "y_train_pred = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 与 cross_val_score 相比\n",
    "* 同样执行交叉验证\n",
    "* 返回的不是评估分数，是每个折叠的预测\n",
    "* 每一个实例在模型预测时使用的数据，在训练期间从未见过"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[53095,  1484],\n",
       "       [ 1117,  4304]], dtype=int64)"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.metrics import confusion_matrix\n",
    "\n",
    "confusion_matrix(y_train_5, y_train_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 行表示实际类别，列表示预测类别\n",
    "# 第一行 第一列 53272 被正确的分为 非5 ，真负类\n",
    "# 第一行 第二列 1307 被错误的分类成 5 ，假正类\n",
    "# 第二行 第一列 1077 张被错误的分为 非5， 假负类\n",
    "# 第二行 第二列 4344 张被正确的分在了5 ，真正类\n",
    "# 这种衡量方式太复杂，我们可以用更简单的指标"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[54579,     0],\n",
       "       [    0,  5421]], dtype=int64)"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_perfect_predictions = y_train_5\n",
    "confusion_matrix(y_train_5, y_train_perfect_predictions)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "\n",
    "## 正类预测的准确率 被称为分类器的精度\n",
    "\n",
    "\n",
    "$\n",
    "\\text{精度} = \\cfrac{TP}{TP + FP}\n",
    "$\n",
    "\n",
    "TP是真正类的数量，FP是假正类的数量\n",
    "\n",
    "\n",
    "\n",
    "$\n",
    "\\text{召回率TPR} = \\cfrac{TP}{TP + FN}\n",
    "$\n",
    "* 检测正类实例的比例\n",
    "FN是假负类的数量\n",
    "![jupyter](./zhaohui.jpg)\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 精度和召回率\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.7436074637180373"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.metrics import precision_score, recall_score\n",
    "\n",
    "precision_score(y_train_5, y_train_pred) # 4327 / 4327 + 1276"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.7939494558199595"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recall_score(y_train_5, y_train_pred)    #  4327 / 4327 + 1094"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 说明 检测一张图的时候，只有90%的概率是准确的，而且只有64%的数字5 被它检测出来\n",
    "# 精度和召回率合成单一指标，成为 F1 分数，谐波平均值\n",
    "# 平均值平等对待所有的值，谐波平均值会给予较低值更高的权重，只有召回率和精度都很高时，才能获得较高的F1分数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$\n",
    "F_1 = \\cfrac{2}{\\cfrac{1}{\\text{precision}} + \\cfrac{1}{\\text{recall}}} = 2 \\times \\cfrac{\\text{precision}\\, \\times \\, \\text{recall}}{\\text{precision}\\, + \\, \\text{recall}} = \\cfrac{TP}{TP + \\cfrac{FN + FP}{2}}\n",
    "$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.7679543224194842"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.metrics import f1_score\n",
    "f1_score(y_train_5, y_train_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "# F1分数对那些具有相近精度和召回率 分类器更有利，这不一定符合你的期望\n",
    "# 有时候你更关心精度，有时你能关心召回率\n",
    "# 训练一个分类器检测儿童可以放心观看的视频，你可能要求拦截了很多好的视频，低召回率，保留下来的都是安全的视频，高精度\n",
    "# 不能同时增加精度并减少召回率，反之亦然"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 精度/召回率权衡"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "![jupyter](./quanheng.jpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* SGDClassifier对每个实例基于决策函数计算一个分值，大于阀值为正类，否则为负类\n",
    "* 中间阀值右侧找到4个真正类 真5 ， 一个假正类 6， 精度为 4/5 80%\n",
    "* 在所有的6个 真正的5 中，分类器找到了4个，召回率为 4/6 67%\n",
    "* 提高阀值，向右移动，精度提高，召回降低\n",
    "* 反之阀值降低，召回提高，精度降低\n",
    "* SKlearn不可以直接设置阀值，可以访问决策分数，\n",
    "* SGDClassifier 默认阀值为0 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 如何设置阀值\n",
    "\n",
    "# 用predict_proba得到每个实例属于正类的概率，然后对概率切一下。以LogisticRegression为例\n",
    "# clf = LogisticRegression()\n",
    "# clf.fit(X_train, y_train)\n",
    "# pred_proba = clf.predict_proba(X_test)[:, 1]\n",
    "# threshold = 0.75  # 阀值设置为0.75\n",
    "# pred_label = pred_proba > threshold\n",
    "\n",
    "# pred_proba是每个实例为真的概率\n",
    "# 假设阈值是0.75\n",
    "# pred_label里True就是概率大于0.75的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1023.90743273])"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 返回决策值decision_function\n",
    "y_scores = sgd_clf.decision_function([some_digit])\n",
    "y_scores"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [],
   "source": [
    "threshold = 0\n",
    "y_some_digit_pred = (y_scores > threshold)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ True])"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_some_digit_pred"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False])"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 提高阀值可以降低召回率，提高阀值到200000，就错了这个图\n",
    "threshold = 200000\n",
    "y_some_digit_pred = (y_scores > threshold)\n",
    "y_some_digit_pred"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 如何决定使用什么阀值\n",
    "# 返回决策值，而不是预测结果\n",
    "y_scores = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3,\n",
    "                             method=\"decision_function\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(60000,)"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 有了y_scores，可以计算所有可能的阀值的精度和召回率\n",
    "y_scores.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import precision_recall_curve\n",
    "\n",
    "precisions, recalls, thresholds = precision_recall_curve(y_train_5, y_scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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GX+962s++QR69IDRowMOSkQqNbma8eEudT77LIwZ4y1PmwY33FBz2eghuc84Az75JHa566/33gtg8eJDRyuKh7Vr15Kamlo5yMn8+fNZsmQJd999Nx06dKB79+6UlZVx0UUX8fnnn/Ozn/2MU045hUWLFnHvvfeyfft2Hn30UQB27NjB2Wefzfbt27nrrrs49dRTKSwsZNasWZSUlJCZmXnI8V9++WXGjx/PpEmTOPfccykuLmbZsmVs3769xpg3bdrEd77zHVq0aMFTTz1Fbm4uTz/9NCNHjuTNN9/k4sioEr7LLruM6667jltvvZU//vGP3H333XTp0oXrrrsujn9JqUkkGW8q2sS338K6dd78xSISDk0uGSeC8vJyysrKKCoq4rXXXuMPf/gD3/3ud8nJyQG8hLp48WI6Ro3Y/9JLL/H++++zYMECBg8eDMAFF3gjK91zzz1MnDiRDh068Pjjj7NmzRoKCgo47bTTKl9/5ZVX1hjPBx98wKmnnsqkSZMqt40YMeKw5/DYY4+xY8cOPvjgg8om9xEjRtCnTx/uvPPOQ5Lx+PHjKxPv0KFDee+99/jd736nZNxIWme3Ji0ljV0HdrGpcD+QRdu2QUclIhFNrpnauZofkVoxeMuHKxtt8eKay0VqxRC/WnHv3r1JT0+nTZs2jB07lquuuornn3++cv/AgQOrJGKAuXPn0q1bN84++2zKysoqHxdeeCGlpaUsWrQIgLfffpsBAwZUScS1GTBgAEuWLOGWW27h3XffZd++fbW+5q9//SsDBw6sTMQAqampXHnllSxZsoTdkemAfCNHjqyy3rdvX77++us6xyhHJ8VSaJ/THoCvt3njfSsZi4SHasYBmDFjBnl5ebRo0YJu3bodMivRsccee8hrCgsL+eqrr0hPT4/5ntu2bat87tevX73iGT16NPv37+e5555j6tSppKenM2LECB577DG6d+8e8zXbt2+PmfA7duyIc44dO3bQsmXLyu1t2rSpUi4zM1PjTjeyY5ofw+Y9m/n93G+BLqxdG3REIhKhZByAvn37VqlRVhfrHuC2bdvSo0cPXnvttZiviSTNdu3asXHjxnrFY2bccMMN3HDDDezYsYO3336b8ePHc/nll/Phhx/GfE2bNm345ptvDtn+zTffYGaHJF8JXpts7zPZXrwDgFatgoxGRKI1uWbqZDV8+HDWr19P8+bNyc/PP+TRrl07wLtV6qOPPmLp0qVHdJzWrVtz+eWX84Mf/IDPPvusxnLnnXceixYtYt26dZXbysvLefXVVznttNNo0aLFER1fGk7rrNYAnHiql4zPPz/IaEQkmmrGTcRVV13FCy+8wAUXXMD48ePp168fJSUlfPnll8yePZuZM2eSk5PDrbfeym9/+1uGDh3KXXfdxSmnnMLWrVuZNWsWzzzzTMwkOWbMGFq0aMGgQYPo0KEDX3zxBS+99BIX1jSLAHDrrbcyffp0hg0bxj333EPLli2ZOnUqX3zxReWtWBIuuZm5APTut5uBE6F//4ADEpFKSsZNRHp6OvPmzePBBx9k2rRprF27lmbNmtGzZ09GjhxZOShIq1atWLhwIXfddRcPPvgg27Zt45hjjuH888+vceCQc845hxdeeIGXXnqJXbt20alTJ66++mruOcwQTZ06deL9999n4sSJ3HTTTRw4cID+/fvz1ltv1Xt0L2kcLTO9a/jH993JbWNqKSwijcpc9a7FjSQ/P98VFBTUuH/FihWcdNJJjRiRhJG+B/EzZcEU7v7L3dx17l3ce/69tb9AROLKzBY75/Jj7dM1Y5EkEblmvHTVdubNgz17Ag5IRCopGYskidbZXjKe/8EOhg+HzZsDDkhEKikZiySJSAeukpSdAKjDu0h4KBmLJInmGd7Y5yVuLwDNmgUZjYhEUzIWSRLNMvzsm+4Nd1pt4DcRCZCSsUiSyEn3JiIhfR9paVDDyKoiEgAlY5Ek0Szdrxln7MWfIExEQkLJWCRJHKwZ7yU7O9hYRKQqJWORJBEZgSur5R6WLQs4GBGpQslYJElkpWWRaqnsL99P67alQYcjIlGUjBvR9OnTMbPKR0ZGBj179uSOO+4IfG7f7t27c+2111auR2KNnpVJmjYzo0Wmd3PxV98UBRyNiETTRBEBeP3118nLy6OoqIgZM2bwwAMPUFRUxJNPPhl0aJLgUspygJ2c0GcfbpfmnBYJizrVjM1suJmtNLPVZnZ7jP1dzWy+mX1qZsvMbET8Q00c/fv3Z+DAgQwbNoypU6cydOhQnnvuOSoqKoIOTRJcZqrXcyujWXHAkYhItFqTsZmlAk8DFwN9gCvNrE+1YncBrznnTgOuAKbGO9BEdvrpp1NcXMzWrVsrt61du5arrrqK9u3bk5mZSf/+/ZkxY8Yhr126dCmXXXYZbdu2JTs7m169evHAAw9U7n/77bcZMWIExx57LDk5OfTt25dHH32U8vLyRjk3CZd085Lx2YOVjEXCpC7N1GcCq51zawDM7BXgUuDzqDIOaOkv5wKb4hlkhN1jDfG29ebuju+0k+vWrSM3N5e2bdsCsH79es466yw6dOjA448/Tvv27Xn11Vf53ve+x8yZMxk1ahQAH330EUOGDOH444/n8ccfJy8vj1WrVrEsqqvsmjVruOCCC7jlllvIysqioKCAyZMns2XLFh588MG4noeEX7rzbm9Kz1YyFgmTuiTjzsD6qPUNwFnVykwG3jazW4BmwNBYb2RmY4AxAF27dq1vrAmjvLycsrKyymvGv//973niiSdITU0FYPLkyTjnWLBgQWWCvuiii1i/fj2TJk2qTMa33XYbbdu2ZdGiReT4ozicf/75VY514403Vi475zj33HMpKSnhkUce4f777yclRX34kkkaXs04JUvJWCRM6pKMY1VHq1cNrwSmO+ceNbNBwEtm1tc5V+UiqHNuGjANID8/v97Vy3jXSIPSu3fvKutjx45l3Lhxletz585lxIgR5ObmUlZWVrn9oosuYsKECezevZu0tDQWLlzIhAkTKhNxLJs3b2by5MnMnTuXTZs2VXm/wsJCOnbsGMczk7BLrfCScWqGkrFImNQlGW8AukSt53FoM/QPgeEAzrkPzCwLaAcUxiPIRDNjxgzy8vLYsmULjz32GFOnTuWss85i9OjRgJckX3zxRV588cWYr9+2bRsZGRlUVFSQl5dX43EqKioYNWoUmzZtYvLkyfTu3Zvs7GxmzpzJz3/+88Bvp5LGl1rh/cMtJXNfwJGISLS6JOOPgRPMrAewEa+D1r9VK/M1cAEw3cxOArKALfEMNJH07duX448/HvCalU899VQmTJjA9773PZo1a0bbtm0599xzmThxYszXd+rUifLyclJSUti4cWONx/nyyy8pKCjgpZde4uqrr67c/sc//jG+JyRNRtvcHNgOnXsoGYuESa0XDJ1zZcA4YB6wAq/X9HIzm2Jmo/xi44HrzWwp8DvgWudcYrQpN7DMzEwefvhhCgsLmTrV64Q+fPhwli1bxsknn0x+fv4hj8zMTHJycvjOd77Db37zG4qLYzc57tvn/Q83PWp6ntLSUl5++eWGPzEJpRO7ezXj0wYo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\n",
      "text/plain": [
       "<Figure size 576x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 使用matplotlib 绘制精度和召回相对于阀值的函数图\n",
    "def plot_precision_recall_vs_threshold(precisions, recalls, thresholds):\n",
    "    plt.plot(thresholds, precisions[:-1], \"b--\", label=\"Precision\", linewidth=2)\n",
    "    plt.plot(thresholds, recalls[:-1], \"g-\", label=\"Recall\", linewidth=2)\n",
    "    plt.xlabel(\"Threshold\", fontsize=16)\n",
    "    plt.legend(loc=\"upper left\", fontsize=16)\n",
    "    plt.ylim([0, 1])\n",
    "\n",
    "plt.figure(figsize=(8, 4))\n",
    "plot_precision_recall_vs_threshold(precisions, recalls, thresholds)\n",
    "plt.xlim([-700000, 700000])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.rcParams['font.sans-serif'] = ['SimHei']\n",
    "def plot_precision_vs_recall(precisions, recalls):\n",
    "    plt.plot(recalls, precisions, \"b-\", linewidth=2)\n",
    "    plt.xlabel(\"召回\", fontsize=16)\n",
    "    plt.ylabel(\"精度\", fontsize=16)\n",
    "    plt.axis([0, 1, 0, 1])\n",
    "\n",
    "plt.figure(figsize=(8, 6))\n",
    "plot_precision_vs_recall(precisions, recalls)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 通过选择阀值来实现最佳的精度/召回率权衡"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 目标设定为90%的精度，阀值大概在30000左右 , 设置了阀值为30000\n",
    "y_train_pred_90 = (y_scores > 30000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9552238805970149"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "precision_score(y_train_5, y_train_pred_90)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.01180593986349382"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recall_score(y_train_5, y_train_pred_90)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 总结\n",
    "* 获得了一个90%精度的分类器，但如果召回太低，精度再高，也不怎么有用\n",
    "* 如果工作中，需要99%的精度，你应该回应，召回率是多少？"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## ROC 曲线"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 本质是 真正类率tpr和假正类率fpr（错误的分为正类的负类实例比例）\n",
    "# 与召回/精度曲线非常相似"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import roc_curve\n",
    "\n",
    "fpr, tpr, thresholds = roc_curve(y_train_5, y_scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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jQQCAYqKipwuSUREXM4doe90AVW0ePFi0tPTWbZsGY899hj//e9/iYuLc7osERFxOVeM6dclBQUFjBs3jkaNGrFkyRI6derkdEkiIhIhXBH6daF7f8uWLaSlpREfH89bb73FKaecQnx8vNNliYhIBHFF935t99xzz9GpUyfuueceADp37qzAFxGRsHNF6NfWS/by8/OZMGECI0aMoGPHjlx22WVOlyQiIhHMFaFfG33++edkZGQwd+5cbr31VpYtW8bJJ5/sdFkiIhLBNKZfQwoLCykoKGDJkiUMGDDA6XJERETU0q9Oe/bsYe7cuQD06NGDDRs2KPBFRKTWUOhXk/fff5+uXbvy+9//nh9++AGAmJgYZ4sSERE5hCtCf2dusWOv7fP5mD59Oueccw5xcXF88sknGrsXEZFayRVj+i0aOLOanbWWX//617z55puMGTOGhx9+mKSkJEdqERERqYgrQt+piXzGGC677DJGjhzJmDFjnClCRESkktwR+mF8raKiIiZPnky3bt0YP348o0ePDuOri4iIHDtXjOmHq6m/bt06evbsyUMPPcS3334bltcUERGpLmrpV4K1lieffJLrr7+e+Ph4Xn/9dc4///waflUREZHq5YqWfk039DMzM7nyyivp2bMnWVlZCnwREamTXNLSr5nU37VrF6mpqZxxxhksWrSIc889F6/XWyOvJSIiUtPU0i9HIBDgH//4ByeffDKrVq0CYMiQIQp8ERGp01zS0q8+O3bsYOzYsSxevJiLL76YU089tRrPLiIi4hy19A+xePFi0tPTef/993nsscd44YUXSElJqZ6Ti4iIOMwlLf3qSf1PPvmExo0b884779CxY8dqOaeIiEht4YqW/vFk/vfff89HH30EwJQpU1i1apUCX0REXMkVoX+smb9gwQK6du3KhAkT8Pv9eL1e4uKcWcdfRESkprkj9Ks4qJ+fn88VV1zBZZddRufOnVm0aJFm5ouIiOu5ZEy/8nbt2sXZZ5/N+vXrmTJlCrfffjtRUa54G0RERI7KFWlXlYZ+48aNOeecc3j00Uc555xzaq4oERGRWsYl3ftHf37Pnj2MGjWK77//HmOMAl9ERCKSO0L/KB38y5YtIz09nRdeeOHA6noiIiKRyB2hX07m+3w+pk+fzoABA4iPj2f58uUMHz48/MWJiIjUEq4I/fLMmjWLv/3tb4wePZrVq1fTrVs3p0sSERFxlEsm8h1s6ufl5ZGYmMgf/vAHTjnlFC6++GIHKxMREak9XNHSN0BRURHXXXcdPXr0ID8/n4SEBAW+iIjIIcIe+saYOcaYT4wxU47nmEP9uHEDPXv25OGHH2bo0KG67l5ERKQcYQ19Y8zvAK+1thfQ2hjT5liOOZS/IIdJI89j27ZtvP7668yaNYvY2Nia+QFERETqsHC39PsDz4duLwbOOsZjDggUZtOuS3eysrI4//zzq6lMERER9wl3P3gCsDV0ey9Q3pT6Co8xxlwNXB26W5y18sMvWrRoUc2lymEaA7udLsLl9B7XPL3HNU/vcXi0PZZvCnfo5wFl29glUn5PQ4XHWGtnA7MBjDGZ1tqM6i9VDqX3uebpPa55eo9rnt7j8DDGZB7L94W7e381B7vr04EfjvEYERERqaJwt/RfBj4w1tvJ6QAACLxJREFUxqQB5wEjjDEzrbVTjnLMmWGuUURExJXC2tK31uYQnKi3HDjHWpt1WOCXd0x2BaedXQOlyi/pfa55eo9rnt7jmqf3ODyO6X021trqLkRERERqIVesyCciIiIVqzOhXxMr+cnPVfT+GWOSjTFvGmMWG2NeMsbEhLtGN6js76kxpqkx5tNw1eUmVXiPHzHG/CpcdblJJf5epBhj3jDGZBpj/h3u+twi9Hfgg6M8H22M+Z8x5iNjzBUVna9OhH5NrOQnP1fJ928UMMtaOxjYDgwNZ41uUMXf0/s4ePmqVFJl32NjzNlAM2vt/8JaoAtU8j0eA/wndPlekjFGl/FVkTEmBZhHcP2aI7keWG2t7QNcYoxJOto560ToUwMr+ckv9KeC989a+4i19u3Q3VRgZ3hKc5X+VOL31BgzAMgn+OFKqqY/FbzHxpho4HHgB2PMb8JXmmv0p+Lf4z1AJ2NMA6AlsCU8pbmKHxgO5BzlmP4c/G/xPnDUD1d1JfQPX6Wv6TEeI0dW6ffPGNMLSLHWLg9HYS5T4fscGjaZCtwcxrrcpDK/y2OBr4B/AP+/vfuPtbqu4zj+fAFX0DItnT/WVGo0f0UBKzBrJSnDH6tw1hrpBrZmOFNRtwo209rKWhuLQltY2lpllhXG8kdSUrbSshZF0cyVzsBabVESCBGv/vh8zuXL2b3cc+HeS+fc12M745zv93M+58Nn9973+X4+38/7M1vS1WPUtl7RSR//GDgFuAbYVMvFMNj+Vwcr2IYV+7ol6I9IJr/Yr476T9JLgM8AQ84dxYA66ecPArfZ3jpmreotnfTxTGC17b8AXwbmjlHbekUnfXwTsMT2R4DfA5ePUdvGm2HFvm4JjMnkN/qG7L96BfoNYJntp8euaT2lk5/T84CrJK0HZkj6/Ng0rWd00sdPAi+vz18D5Od5eDrp4xcD0yVNBOYAWR8+OoYV+7pinb6kFwGPAN+nZvID3tFM7DNAmbM6GBaJqsM+vhL4GLChHvqs7bvHuq3drJN+biu/3vY5Y9fC7tfhz/KRwB2UodA+4O22Nw9QXQygwz6eDdxJGeL/KXCx7W2HoLldr/V3oN7rc4btVY1zpwD3AeuAsymx77+D1tUNQR/672KcB/yoDskdUJkYXPpvbKSfR1/6ePSlj/9/1LT1bwAeHOpit2uCfkRERBycbpnTj4iIiIOUoB8RETFOJOhHxKiTNFGSDnU7Isa7BP2IHiFpgaSzBzk3ZTT3SpA0X9INjde3SHqwUeRDwNq6fKuT+i6tSaAiYgRNOtQNiIgRcyPwA0krKOuiW5YBU4GFkkxJ4HGV7c8BSJoJPM/Q66gnAlOA39je1Xbun8ByScfZ/gCwE9hR678QeD/wrvalRDUd7iRgp+09jVPvBrYDb2mUnQgcBuyxvXOItkbEABL0I3qApJOB6cBbgdnAXNvrJX2RElCXAEtq2fWULF4tj1KCdDPoHkYJ8M2c3xPq8VOpyWwkTQYE/Ay4CFg5wIYf1wNX2m7tzDjB9vP13DuBVcAOSa1A3kf5ArJb0lONevqAIygbEX20o46JiH0k6Ef0hkWUnbY216v5ofRfcdue3H5S0mLgZttTh6jnE8C1bcf6vyg02nKupDvr83uBBfX5XfXfB2z/vb7nLuDoWmYG8HPbe+pObhdR0kBHxAHInH5El5M0CXgP5Wq95eEacBcBUyStk/ScpK2UJB7726pzOG4GjgH6bAuYBjwLPEEJ7qcD36FML0ygjB4sbLz/cOAs4AlJ8yTdA5xAydu+HPghcEHdJ/xx4MRaR0QcgFzpR3S/yynz9E1zba9vvZC0kjJ8v9MDZOSSdC2w3fbtw/ng5qZANUXoV+vjOcqmNtsoXzA2AjfYXt32/m3A+yStBnYBl1BGCh6ifCG42PZ3630Hi2yvGU77ImJfudKP6GJ1Lv/jwG2DnJ8i6TjKVrILgUWSFkt6ZVvRecAb245NkHR043GspBMH+IxX1yH5tcAttq+nzP1Ptv3nWvdNwK2S1tb2tPs3sJVyX8KbKfcJXAa8VNIsyt7s07LsL+LgJOhHdLctlID6i7bjreH9HcBJwCeBSynz5CuAV7SV301jnr86CfhH4/E34P5mAUmvBX5JucFuhu2VjXZtlTTRxQrKxiwn0/Z3R9IFwGPAuZRRgXspd+9/E5hP2RhnKmUVwj2SjhiqUyJiYAn6EV3M9u7mjlsNc+sc++GUoHwfsMr2Asow+uMdVP+0bbUelLvn2/MAbATOtP02239oOzebxooA2+vqsf6VA5KWA1+ijERsouzGdiTwacoywDnAmcAsyha4r6Lc8R8RByBz+hE9qg6Ft4bD1wHnS/o1Ze7+meHWZ3s3ZUSg6X7gTfsZdd8zyDlJmgB8Dfi67SfrwTmU/cC/APzR9tK6Resztp+VNANwHUEYdPvQiBhYgn5Eb3q48fxlwLcoWfEM3DqCn3NhrbM/uY6kU4FfAZuBtbavaxWu6/RbSwSnU6YldklqT/bzAsoXhsWN98LeXAHzKXf2R8QwJOhH9KZWcp4+YLdtS/oeZa78hJH6ENvbm6/rvt5foQzZfxj4SR1xWGZ7R83kt6u+dwOD/A2StAZ4yvbSkWprRGROP6JXTGTv73Nf66Dt/wAvlHQjcD6wAbhD0vF1E5wZkk6nLPk7StJpkk6jrIfva72ujzNq+WntHy7pGEnXUa7wNwHX2N4CvI4yF79R0tWSjhq9LoiIoeRKP6I3TGFv0pr+DHt1A54HKHfEz6Lchf8p4HeUm+IeY9+8+4+21dv+uq/Wd0mtfyllKeBM4LfAe21/u1W4zsOfA1xBSeSzQtLdti8b4v/T/BITESNEA+TpiIgeIul4239tO3ZsK+3tQdb9euA8YE0drt9f2cmUJYNbbD8yRNmHgD/ZvuJg2xgReyXoR0REjBMZPouIiBgnEvQjIiLGiQT9iIiIcSJBPyIiYpxI0I+IiBgnEvQjIiLGif8BVEv68zvwd08AAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 576x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.rcParams['font.sans-serif'] = ['SimHei']\n",
    "def plot_roc_curve(fpr, tpr, label=None):\n",
    "    plt.plot(fpr, tpr, linewidth=2, label=label)\n",
    "    plt.plot([0, 1], [0, 1], 'k--')\n",
    "    plt.axis([0, 1, 0, 1])\n",
    "    plt.xlabel('假正类率', fontsize=16)\n",
    "    plt.ylabel('真正类率', fontsize=16)\n",
    "\n",
    "plt.figure(figsize=(8, 6))\n",
    "plot_roc_curve(fpr, tpr)\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.961576942607278"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 计算曲线下面积AUC，虚线是随机分类0.5到1\n",
    "from sklearn.metrics import roc_auc_score\n",
    "\n",
    "roc_auc_score(y_train_5, y_scores)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 召回率TPR越高，分类器的假正类FPR就越多\n",
    "* 虚线表示纯随机分类器的ROC曲线，好的分类器应该远离这条线，向左上角\n",
    "* 是使用精度/召回率 PR曲线，还是使用ROC，关键在于 正类非常少或者更关注假正类而不是假负类，选择PR，反之ROC\n",
    "* 例如：前面例子ROC曲线很不错是因为跟负类 非5 相比， 正类 数据5 数量真的很少"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练随机森林分类器，比较SGD分类器的ROC曲线和ROC AUC分数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 获取训练集中每个实例的分数\n",
    "* RandomForestClassifier 没有decision_function(),但是拥有dict_proda()方法，sklearn中分类器都有这两个中的一个\n",
    "* dict_proda返回一个矩阵，每行一个实例，每列代表一个类别的概率，比如这个图片 70%是5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.ensemble import RandomForestClassifier\n",
    "forest_clf = RandomForestClassifier(n_estimators=10, random_state=42)\n",
    "y_probas_forest = cross_val_predict(forest_clf, X_train, y_train_5, cv=3,\n",
    "                                    method=\"predict_proba\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1. , 0. ],\n",
       "       [1. , 0. ],\n",
       "       [1. , 0. ],\n",
       "       ...,\n",
       "       [1. , 0. ],\n",
       "       [1. , 0. ],\n",
       "       [0.8, 0.2]])"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_probas_forest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 绘制ROC曲线，需要决策值不是概率，直接使用正类的概率作为决策值：\n",
    "y_scores_forest = y_probas_forest[:, 1] \n",
    "fpr_forest, tpr_forest, thresholds_forest = roc_curve(y_train_5,y_scores_forest)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0. , 0. , 0. , ..., 0. , 0. , 0.2])"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_scores_forest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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qUKNGjV45513aNq0qddxRMSHTnpO31r7grU27gTPHwHOA3am/Lz6BLsLB7alPN5LJrfhNcaEAsOAR7PaiTGmnzEmyhgTdbL8InnZP//8Q//+/YmJiSEsLIzPP/9cBV9Eck2OLONlrf3LWpvZjP6MDpE2ZF8si+M/Crxurd1/guONt9ZGWmsjAT7/zHDo0KmmFvHWwoULiYiIYNKkSSxdutTrOCJSAAR67c6VuCF9gAjgz0y2aQXcZYz5BqhrjHn7ZDv94AM4fDinIorkrsTERIYMGUKrVq0oUaIEy5cv153xRCQgsjt7P6d8CnxnjKkCtAe6GGNGWWuHpm5grf13bNMY8421tu/Jdnr99RAenit5RXLcww8/zAsvvMBtt93Gyy+/TLj+8opIgJjsjcrn4AGNKY1byOdba222JuqdSFjl6vb92d9ww2VVzzycSC6Kj48nNDSUbdu2sXjxYjp37ux1JBHJp4wxK1NPcZ+KgN+ay1q7z1o7MycKvkh+cPjwYfr370+HDh1ITk6matWqKvgi4glf3I9zyxZIOtFFhSIe+fHHH2nYsCHjx4+nXr16JCcnex1JRAowXxT9Rx/VinySt1hreeONN2jQoAG7d+9m7ty5jBkzhkKFAj2NRkQkjS+K/jnngBYuk7zk0KFDjB49mmbNmhEdHU3r1q29jiQiEvDZ+7lizBgokq0Fe0Vy18qVK6lduzbFixfn+++/p2rVqgQF+eKztYj4gN6NRHJAUlISTz31FI0aNWLs2LEAnH322Sr4IpKn+KKnL+Kl7du30717d77++mu6du3KPffc43UkEZFM+aIbcs/dEODlBkSAtKV0ly1bxoQJE3j33XcpUaKE17FERDLli57+vn1gjNcppCAqX748F154IRMnTuSSSy7xOo6IyAn5oqf/0steJ5CC5JdffuHpp58GoHbt2vzwww8q+CKSL/ii6Jct63UCKSimTJlCvXr1eO6559i+fTsARsNMIpJP+KLoi+S2gwcP0qNHD3r16kX9+vWJjo6mSpUqXscSETklvij606appyW5x1pLixYtmD59OiNGjGDhwoWcddZZXscSETllvpjI983XXicQP0pOTsYYgzGGYcOGUapUKZo2bXryF4qI5FG+6Ol37+51AvGbXbt20aFDB1599VUArr/+ehV8Ecn3fFH0r27hdQLxkwULFhAREcHC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+APJFVf6iTf5t3xVJTMzkylTphAdHc26desYOHCgfw9qjLlu1PQK+3qRnJxMcnIygwYNYuHChQwfPhyA7777jpSUFFq2bMnIkSOZM2cOr7zyyhWfr+j2t+LiYurVK33tGBYWVup12QRe8lo9/fq1oV27dqV+WJTlG0NFx+/atesVnyvZ56233qJdu3altpX8cHrwwQf5+9//zoYNG8jKymLAgAH85Cc/YfHixTU7GT9zxZW+v+3atYtx48bRvXt39u3bZwnfGBOSZs2axZ49e9jkWZp0y5Yt5Obmsn79ep566inuuOOOclsxyybyEomJiZw8edJ71Qvwl7/8xfs8OTmZb775ptRVdVZWFtHR0bRv3762TqtCt956K/Xq1SvVVZCVlUW9evW49dZbK/18u3btiIiIoKCgwPvDqWHDhvz85z/n9OnTALz00kscOXKESZMmsXLlSubNm0dmZmapcqKioq5oPQkWV1zpf/Otf8o9fvw4LVq0oGvXrmzYsIH77ruvwi+/McZc77p168a9997LwoUL6du3r3cEf2ZmJklJSSxZsoS//vWvVZ7Ypn///rRt25Yf//jHzJ49m927d7N69WratGkDwJ133knfvn0ZPnw4L730El9//TXPP/88s2fPDsgcATfeeCPjxo1j0qRJnD9/HlVl2rRpjB8/3nulfjXR0dE8/fTTTJ8+HVWlTZs2ZGRkcPr0aeLj4wH45JNPWLlyJS+88AINGjRg7dq1V9y2nZKSwokTJ1i2bBmdOnVi+/btzJw50x+nXLmajP67nh4R8e102qLaHb1/6dIlXbhwoUZHR+uHH35Yq2UbY65vbh69r6r6pz/9SQHNzs5WVdWf/vSnGhsbq3FxcZqWlqYTJ07Udu3aaVFRkXd0fG5urvfzJaPdS+Tk5Gjv3r01OjpaU1JSdObMmaVG7586dUpHjhypDRs21JYtW2p6erpeunRJVZ3R++np6aqqOmbMGB0zZoyqqqanp+vdd99d6flVZfR+QUGBTp48WWNiYjQmJkYnT56sBQUFFZ5PWRcuXNDp06drixYttHHjxvrQQw/pF198Uer8xowZoy1bttTo6Gi96667dP/+/VeUs2zZMv3+97+v9evX186dO1d6bv4avS9ai/0qwRDZqr3+9MVtPD+2Va2Ud/ToUUaPHs3GjRt5+OGHWb58OU2bNq2Vso0x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\n",
      "text/plain": [
       "<Figure size 576x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8, 6))\n",
    "plt.plot(fpr, tpr, \"b:\", linewidth=2, label=\"SGD\")\n",
    "plot_roc_curve(fpr_forest, tpr_forest, \"Random Forest\")\n",
    "plt.legend(loc=\"lower right\", fontsize=16)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9920155423973993"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Rand 比SGD 好很多，ROC AUC的分数也高很多\n",
    "roc_auc_score(y_train_5, y_scores_forest)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9839100727352876"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 再看一下 精度和召回率 也很高\n",
    "y_train_pred_forest = cross_val_predict(forest_clf, X_train, y_train_5, cv=3)\n",
    "precision_score(y_train_5, y_train_pred_forest)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.823464305478694"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recall_score(y_train_5, y_train_pred_forest)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 总结\n",
    "* 选择合适的指标利用交叉验证来对分类器进行评估\n",
    "* 选择满足需求的精度/召回率权衡\n",
    "* 使用ROC曲线和ROC AUC分数比较多个模型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 多类别分类器\n",
    "* 尝试5 之外的检测\n",
    "* 多类别分类器 区分两个以上的类别\n",
    "* 随机森里和朴素贝叶斯可以直接处理多个类别\n",
    "* 支持向量机svm和线性分类器只可以处理二元分类器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 解决方案\n",
    "1. 将数字图片分类0到9，训练10个二元分类器，每个数字一个，检测一张图片时，获取每个分类器的决策分数，哪个最高属于哪个，称为一对多OvA\n",
    "2. 为每一对数字训练一个二元分类器，区分0，1 区分0，2 区分1，2 称为一对一OvO策略，存在N个类别，需要N*（N-1）/2个分类器，最后看哪个类别获胜最多\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 优缺点\n",
    "* OvO 只需要用到部分训练集对其必须区分两个类别进行训练\n",
    "* 对于较小训练集合OvO比较有优势， 大训练集合 OvA 速度快，所以OvA更常用，比如svm 在数据规模扩大时表现糟糕\n",
    "* sklearn 检查到使用二元分类算法进行多类别分类任务，会自动运行OvA，SVM分类器除外"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([5.])"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sgd_clf.fit(X_train, y_train)\n",
    "sgd_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ -9820.79157056, -30942.30749314,  -4432.10006378,\n",
       "         -2448.22817642, -20367.4006307 ,    984.15186269,\n",
       "        -28286.41240783, -17588.70876178,  -7985.81372302,\n",
       "        -18183.75258472]])"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 内部实际上训练了10个二元分类器，获得图片的决策分数，然后选择了分数最高的类别\n",
    "# 返回10个分数，每个类别1个\n",
    "some_digit_scores = sgd_clf.decision_function([some_digit])\n",
    "some_digit_scores"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.argmax(some_digit_scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 目标类别列表会存储在classes_这个属性中，按值大小排列，\n",
    "sgd_clf.classes_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5.0"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sgd_clf.classes_[np.argmax(some_digit_scores)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([5.])"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 使用OvO策略，一对一或者一对多\n",
    "from sklearn.multiclass import OneVsOneClassifier\n",
    "ovo_clf = OneVsOneClassifier(SGDClassifier(max_iter=5, tol=-np.infty, random_state=42))\n",
    "ovo_clf.fit(X_train, y_train)\n",
    "ovo_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "45"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(ovo_clf.estimators_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([5.])"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 使用随机森林\n",
    "forest_clf.fit(X_train, y_train)\n",
    "forest_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0., 0., 0., 0., 0., 1., 0., 0., 0., 0.]])"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 随机森林直接将实例分为多个类别，调用predict_proba()可以获得分类器将每个实例分类为每个类别的概率列表\n",
    "forest_clf.predict_proba([some_digit])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 评估分类器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.86652669, 0.86034302, 0.87963194])"
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 使用交叉验证评估SGD的准确率\n",
    "cross_val_score(sgd_clf, X_train, y_train, cv=3, scoring=\"accuracy\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.89967007, 0.89844492, 0.90488573])"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 将输入进行简单缩放 ，可以得到准确率 90 %以上\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "scaler = StandardScaler()\n",
    "X_train_scaled = scaler.fit_transform(X_train.astype(np.float64))\n",
    "cross_val_score(sgd_clf, X_train_scaled, y_train, cv=3, scoring=\"accuracy\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 错误分析"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 项目流程\n",
    "1. 探索数据准备的选项\n",
    "2. 尝试多个模型\n",
    "3. 选择最佳模型并用GridSearchCV对参数进行微调\n",
    "4. 尽可能自动化\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 确定了一个相对合适的模型，进一步优化，分析其错误类型\n",
    "* 查看混淆矩阵\n",
    "* 使用cross_val_predict()进行预测\n",
    "* 调用confusion_matrix()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[5592,    0,   13,   10,   10,   38,   35,    9,  215,    1],\n",
       "       [   0, 6421,   42,   25,    3,   39,    6,    8,  188,   10],\n",
       "       [  28,   23, 5253,   89,   68,   24,   71,   38,  355,    9],\n",
       "       [  26,   19,  113, 5271,    1,  194,   23,   43,  383,   58],\n",
       "       [  14,   13,   41,   12, 5239,    5,   35,   21,  313,  149],\n",
       "       [  24,   14,   35,  171,   53, 4476,   74,   16,  497,   61],\n",
       "       [  28,   15,   48,    3,   42,   95, 5544,    8,  135,    0],\n",
       "       [  19,   14,   50,   24,   48,   14,    5, 5707,  172,  212],\n",
       "       [  14,   66,   39,   93,    3,  111,   30,    9, 5442,   44],\n",
       "       [  22,   23,   31,   59,  121,   33,    1,  185,  359, 5115]],\n",
       "      dtype=int64)"
      ]
     },
     "execution_count": 74,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_pred = cross_val_predict(sgd_clf, X_train_scaled, y_train, cv=3)\n",
    "conf_mx = confusion_matrix(y_train, y_train_pred)\n",
    "conf_mx"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 288x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 使用matplotlib的matshow 函数来查看混淆矩阵的图像表示\n",
    "plt.matshow(conf_mx, cmap = plt.cm.gray)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 看起来不错，大多数图片都在主对角线上，说明它们被正确分类\n",
    "# 数字5 看起来比较暗，说明1. 数字5图片较少  2. 分类器在数字5上执行效果不如其他数字上好\n",
    "# 假设把焦点放在错误上，为取得错误率，而不是错误绝对值，需要将混淆矩阵中每个值除以相应类别中的图片数量\n",
    "\n",
    "row_sums = conf_mx.sum(axis=1, keepdims=True)\n",
    "norm_conf_mx = conf_mx / row_sums"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 288x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 用0填充对角线 只保留错误，重新绘制\n",
    "np.fill_diagonal(norm_conf_mx, 0)\n",
    "plt.matshow(norm_conf_mx, cmap=plt.cm.gray)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 每行代表实际类别，每列代表预测类别\n",
    "# 8，9列比较亮，说明许多图片被错误的分类为数字8，9\n",
    "# 类别8，9行也偏亮，说明数字8和9经常会跟其他数字混淆\n",
    "# 有些很暗，比如行1，大多数数字1都被正确的分类，一些和8混淆\n",
    "# 5和3是错误最多的"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 结论\n",
    "* 改进数字8和9的分类\n",
    "* 修正数字3和5的混淆\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 如何优化分类器\n",
    "* 尝试多收集这些数字的训练集\n",
    "* 开发一些新特征来改进分类器\n",
    "* 优化分类器算法\n",
    "* 使用pillow或opencv对图片预处理，让显示模型更突出\n",
    "* 分析单个错误"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x576 with 4 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def plot_digits(instances, images_per_row=10, **options):\n",
    "    size = 28\n",
    "    images_per_row = min(len(instances), images_per_row)\n",
    "    images = [instance.reshape(size,size) for instance in instances]\n",
    "    n_rows = (len(instances) - 1) // images_per_row + 1\n",
    "    row_images = []\n",
    "    n_empty = n_rows * images_per_row - len(instances)\n",
    "    images.append(np.zeros((size, size * n_empty)))\n",
    "    for row in range(n_rows):\n",
    "        rimages = images[row * images_per_row : (row + 1) * images_per_row]\n",
    "        row_images.append(np.concatenate(rimages, axis=1))\n",
    "    image = np.concatenate(row_images, axis=0)\n",
    "    plt.imshow(image, cmap = matplotlib.cm.binary, **options)\n",
    "    plt.axis(\"off\")\n",
    "\n",
    "\n",
    "# 查看数字3和数字5的例子\n",
    "cl_a, cl_b = 3, 5\n",
    "X_aa = X_train[(y_train == cl_a) & (y_train_pred == cl_a)]\n",
    "X_ab = X_train[(y_train == cl_a) & (y_train_pred == cl_b)]\n",
    "X_ba = X_train[(y_train == cl_b) & (y_train_pred == cl_a)]\n",
    "X_bb = X_train[(y_train == cl_b) & (y_train_pred == cl_b)]\n",
    "\n",
    "plt.figure(figsize=(8,8))\n",
    "plt.subplot(221); \n",
    "plot_digits(X_aa[:25], images_per_row=5)\n",
    "plt.subplot(222); \n",
    "plot_digits(X_ab[:25], images_per_row=5)\n",
    "plt.subplot(223);\n",
    "plot_digits(X_ba[:25], images_per_row=5)\n",
    "plt.subplot(224); \n",
    "plot_digits(X_bb[:25], images_per_row=5)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 左侧两个是被分类为3的图片\n",
    "# 右侧两个是被分类为5的图片\n",
    "# 大多数错误分类的图片看起来还是非常明显的错误\n",
    "# 原因：SGD是一个线性模型，它所做就是为每个像素分配一个各个类别的权重，当它看到新的图像，将加权后的像素强度汇总，从而得到一个分数进行分类\n",
    "# 数字3和5在一部分像素位上有区别，所以分类器很容易将其弄混\n",
    "# 通过上面图像，如果书写3 的连接点左移，分类器可能将其分类为数字5，这个分类器对图像位移和旋转敏感\n",
    "# 减少混淆的方法之一，就是对图像进行预处理，确保位于中心位置并且没有旋转"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 多标签分类"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 为每个实例产生多个类别 ，例如 照片识别多个人脸\n",
    "# 分类器经过训练可以识别小红，小白，小军，一张照片 里有 小红，小白\n",
    "# 经过分类器，应该输出[1,1,0]， 是小红，是小白，不是小军\n",
    "# 输出多个二元标签的分类系统称为多标签分类系统"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
       "                     metric_params=None, n_jobs=None, n_neighbors=5, p=2,\n",
       "                     weights='uniform')"
      ]
     },
     "execution_count": 82,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "\n",
    "y_train_large = (y_train >= 7)\n",
    "y_train_odd = (y_train % 2 == 1)\n",
    "y_multilabel = np.c_[y_train_large, y_train_odd]\n",
    "\n",
    "knn_clf = KNeighborsClassifier()\n",
    "knn_clf.fit(X_train, y_multilabel)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[False,  True]])"
      ]
     },
     "execution_count": 83,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# knn支持多标签分类，不是所有的分类器都支持\n",
    "knn_clf.predict([some_digit])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.97709"
      ]
     },
     "execution_count": 84,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# # 评估多标签分类器方法很多，方法之一就是测量每个标签的F1分数，或者其他二元分类器指标，然后简单平均\n",
    "# y_train_knn_pred = cross_val_predict(knn_clf, X_train, y_multilabel, cv=3)\n",
    "# f1_score(y_multilabel, y_train_knn_pred, average=\"macro\")\n",
    "0.977090"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 上面假设了所有标签都同等重要，也可以给每个标签设置一个权重（该目标标签实例的数量），设置average='weighted'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 多输出分类"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 例子：构建一个系统去除图片中的噪声，输入一张有噪声的图片，它将输入一张干净的数字图片，分类器输出是多个标签，一个像素一个标签，每个标签多个值0到255"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 增加噪声，目标将图片还原为原始图片 创建训练集和测试集\n",
    "noise = np.random.randint(0, 100, (len(X_train), 784))\n",
    "X_train_mod = X_train + noise\n",
    "noise = np.random.randint(0, 100, (len(X_test), 784))\n",
    "X_test_mod = X_test + noise\n",
    "y_train_mod = X_train\n",
    "y_test_mod = X_test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "some_index = 5500\n",
    "plt.subplot(121);plt.imshow(X_test_mod[some_index].reshape(28, 28), cmap = matplotlib.cm.binary)\n",
    "plt.subplot(122);plt.imshow(y_test_mod[some_index].reshape(28, 28), cmap = matplotlib.cm.binary)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {},
   "outputs": [],
   "source": [
    "knn_clf.fit(X_train_mod, y_train_mod)\n",
    "clean_digit = knn_clf.predict([X_test_mod[some_index]])\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(clean_digit.reshape(28, 28), cmap = matplotlib.cm.binary)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
